package com.example.mfbq.arithmetic;

import android.os.Bundle;
import android.os.Message;

import com.example.mfbq.handler.ArithmeticHandler;

public class FCFSArithmetic {

    private Process[] processes;
    private ProcessQueue queue = new ProcessQueue(0);
    private ArithmeticHandler handler;
    public FCFSArithmetic(Process[] processes, ArithmeticHandler handler){
        this.processes = processes;
        this.handler = handler;
        sortProcess();
    }

    private Process continueProcess;//代表时间片还未结束的进程
    private int delay = 0;
    public void start(){
        int currentTime = 0;
        while (true){
            Process process = hasProcess(currentTime);
            if(process != null){
                queue.add(process);

                //更新界面
                Message msg = new Message();
                msg.what = 0x112;//代表要更新队列区
                msg.arg1 = 0;//代表更新第0号队列
                msg.arg2 = process.getProcessId();//代表队列区加入的内容
                msg.obj = "add";
                handler.sendMessageDelayed(msg, delay*1000);
                delay++;

            }
            Process executeProcess = null;
            if(continueProcess != null){
                executeProcess = continueProcess;
            }else{
                executeProcess = getExecuteProcess();
            }
            if(executeProcess == null && handDownProcess() == false){
                break;
            }else{
                if(executeProcess == null){

                    Message leisure = new Message();
                    leisure.what = 0x114;
                    handler.sendMessageDelayed(leisure, delay*1000);
                    delay++;

                    currentTime++;
                    continue;
                }else{
                    Message msg = new Message();
                    msg.what = 0x111;
                    msg.arg1 = executeProcess.getProcessId();
                    msg.arg2 = currentTime;
                    handler.sendMessageDelayed(msg, delay*1000);
                    delay++;

                    executeProcess.setDoneTime(executeProcess.getDoneTime() + 1);
                    if(executeProcess.getDoneTime() == executeProcess.getServeTime()){
                        executeProcess.setCompleteTime(currentTime + 1);
                        continueProcess = null;

                        Message message = new Message();
                        message.what = 0x123;
                        message.arg1 = executeProcess.getProcessId();
                        message.arg2 = currentTime + 1;
                        handler.sendMessageDelayed(message, delay*1000);
                        delay++;
                    }else{
                        continueProcess = executeProcess;
                    }
                }
            }
            currentTime++;
        }
        Message result = new Message();
        result.what = 0x213;
        Bundle data = new Bundle();
        data.putString("arithmetic", "fcfs");
        data.putString("result", toResultString());
        data.putDouble("art", getAverageRevolveTime());
        data.putDouble("awrt", getWAverageRevolveTime());
        result.obj = processes;
        result.setData(data);
        handler.sendMessageDelayed(result, delay*1000);
    }

    //按照进程到达时间排序
    private void sortProcess(){
        Process[] pro = this.processes;
        Process process = new Process();//用于作为交换媒介
        for(int i = 0; i < pro.length; i++){
            for(int j = 0; j < pro.length - 1 - i; j++){
                if(pro[j].getComeTime() > pro[j+1].getComeTime()){
                    process = pro[j];
                    pro[j] = pro[j+1];
                    pro[j+1] = process;
                }
            }
        }
    }
    //得到队列中将要进行的进程，进程全部结束返回null，否则返回将要执行的进程，将其从原队列弹出
    private Process getExecuteProcess(){
        Process process = this.queue.poll();

        if(process != null){
            Message msg = new Message();
            msg.what = 0x112;
            msg.arg1 = 0;
            msg.arg2 = process.getProcessId();
            msg.obj = "remove";
            handler.sendMessageDelayed(msg, delay*1000);
            delay++;
        }

        return process;
    }
    //判断这一时刻是否有进程到来，有进程到来返回进程对象，无进程到来返回null
    private Process hasProcess(int currentTime){
        for(Process p : this.processes){
            if(p.getComeTime() == currentTime){
                return p;
            }
        }
        return null;
    }
    //判断队列中是否还有进程
    private boolean handDownProcess(){
        for(Process p : this.processes){
            if(p.getDoneTime() != p.getServeTime()){
                return true;
            }
        }
        return false;
    }
    //得到平均周转时间
    private double getAverageRevolveTime(){
        int sum = 0;
        for(Process p : this.processes){
            sum = sum + p.getRevolveTime();
        }
        return ((double)sum) / this.processes.length;
    }
    //得到平均带权周转时间
    private double getWAverageRevolveTime(){
        double sum = 0.0;
        for(Process p : this.processes){
            sum = sum + p.getwRevolveTime();
        }
        return sum/this.processes.length;
    }
    //显示数据
    private String toResultString() {
        String str = "";
//        for(Process p : this.processes){
//            str = str + p.toString() + "\n";
//        }
        str = str + "平均周转时间为："+String.format("%.3f", getAverageRevolveTime())+"\n";
        str = str + "平均带权周转时间为："+String.format("%.3f", getWAverageRevolveTime());
        return str;
    }
}